using System;
using System.Collections.Generic;
using System.Html;
using jQueryApi;

namespace UnitTestHarness
{

    /// <summary>
    /// Client side test harness class.
    /// </summary>
    public partial class TestBase
    {
        /// <summary>
        /// Reset the printed results element for a new printing
        /// </summary>
        public static void ResetPrintout()
        {
            Element el = TestOutputElement;
            Tallies.Reset();
            jQuery.FromObject(TestListObject).Empty();
            TestListObject = jQuery.FromHtml("<div id='testResults'/>").AddClass(TestOutputClass).AppendTo(el);
        }

        /// <summary>
        /// Print the control bar to the container element
        /// </summary>
        /// <param name="el">container element</param>
        public static void PrintControlBar(Element el)
        {
            jQuery.FromHtml("<button/>").AppendTo(el).Html("reset results").Click(delegate(jQueryEvent e)
            {
                Window.LocalStorage.SetItem(StorageKey, TestLogJsonTemplate);
                TestLogResults = LoadResults();
                ResetPrintout();
                DoSuites(200);
            });

            jQuery.FromHtml("<button/>").AppendTo(el).Html("rerun").Click(delegate(jQueryEvent e)
            {
                ResetPrintout();
                DoSuites(200);
            });

            jQuery.FromHtml("<button/>").AppendTo(el).Html("reprint").Click(delegate(jQueryEvent e)
            {
                PrintAllResults();
            });

            jQueryObject tallies = jQuery.FromHtml(@"<div style=""clear:both""/>").AppendTo(el);

            string tally = @"<div class=""tally"" style=""float:left"">{1}<span id=""{0}"">0</span></div>";

            jQuery.FromHtml(String.Format(tally, TestTallies.passedId, "Passed: ")).AppendTo(tallies);
            jQuery.FromHtml(String.Format(tally, TestTallies.failedId, "Failed: ")).AppendTo(tallies);
            jQuery.FromHtml(String.Format(tally, TestTallies.unknownId, "Unknown: ")).AppendTo(tallies);
            jQuery.FromHtml(String.Format(tally, TestTallies.totalId, "Total: ")).AppendTo(tallies);
            jQuery.FromHtml(String.Format(tally, TestTallies.totalTimeId, "Time: ")).AppendTo(tallies);

        }

        public static void PrintSuiteName(string suiteName)
        {
            if (!String.IsNullOrEmpty(suiteName))
                jQuery.FromHtml("<h2/>").Html(suiteName).AppendTo(TestListObject);
        }

        /// <summary>
        /// Print all the results from a testObject dictionary into the test output element
        /// </summary>
        public static void PrintAllResults()
        {
            TestLogCollection collection = TestLogResults;
            ResetPrintout();

            if (CollectionStartTime == null)
                CollectionStartTime = new Date();
            if (CollectionEndTime == null)
                CollectionEndTime = CollectionStartTime;

            foreach (TestLogSuite suite in collection.suites)
            {
                PrintSuiteName(suite.suiteName);

                foreach (TestLogTest test in suite.tests)
                {
                    foreach (KeyValuePair<string, TestLogResult> pair in test.results)
                    {
                        PrintResult(pair.Value);
                    }
                }
            }
        }

        /// <summary>
        /// Print a single test result into the test output element
        /// </summary>
        /// <param name="result">the result to print</param>
        public static void PrintResult(TestLogResult result)
        {
            string id = result.id;
            if (Script.IsNullOrUndefined(result.lastRun))
                result.lastRun = Never;
            if (Script.IsNullOrUndefined(result.lastPassed))
                result.lastPassed = Never;

            jQueryObject Dl = jQuery.FromHtml("<dl/>").AppendTo(TestListObject);

            if (result.backgroundColor != null)
                Dl.CSS("backgroundColor", result.backgroundColor);

            jQueryObject Dt = jQuery.FromHtml("<dt/>").Html(result.label + " [= " + result.lastResult + "]").AppendTo(Dl);

            jQuery.FromHtml("<dd/>").Html("last run: " + LocalTime(result.lastRun)).AppendTo(Dl);
            jQuery.FromHtml("<dd/>").Html("last pass: " + (result.lastPassed == Never ? "NEVER" : LocalTime(result.lastPassed))).AppendTo(Dl);
            jQueryObject lastResult = jQuery.FromHtml("<dd/>").Html("last result: " + result.lastResult).AppendTo(Dl);
            if ((string)result.lastResult == NotAssigned)
                result.passed = (bool)Script.Literal("undefined");
            else if (!result.hasDefault)
            {
                if ((bool)Script.Literal("{0} !== true", result.passed))
                    result.passed = (bool)Script.Literal("undefined");
            }
            jQuery.FromHtml("<dd/>").Html("valid result: " + result.validResult).AppendTo(Dl);
            jQueryObject status = null;
            switch (result.passed)
            {
                case true:
                    status = jQuery.FromHtml("<span/>").AddClass("passed").Html("true");
                    Dl.AddClass("passed");
                    Tallies.Passed++;
                    break;
                case false:
                    status = jQuery.FromHtml("<span/>").AddClass("failed").Html("false");
                    Dl.AddClass("failed");
                    Tallies.Failed++;
                    break;
                default:
                    status = jQuery.FromHtml("<button/>").Click(delegate(jQueryEvent e)
                    {
                        result.validResult = result.lastResult;
                        result.lastPassed = result.lastRun;
                        result.passed = true;
                        SaveResults();
                        PrintAllResults();
                    }).Html("yes this result is valid");
                    Dl.AddClass("unknown");
                    Tallies.Unknown++;
                    break;
            }
            Tallies.Total++;
            Tallies.TotalTime = (CollectionEndTime.GetTime() - CollectionStartTime.GetTime());

            jQuery.FromHtml("<dd/>").Html("passed: ").AppendTo(Dl).Append(status);
            if (!String.IsNullOrEmpty(result.code))
                jQuery.FromHtml("<dd/>").Html("code: " + result.code.Substr(0, 500).Replace("\r", "").Replace("\n", "[xNx]").HtmlEncode().Replace("[xNx]", "<br>")).AppendTo(Dl);
            jQuery.Select("#testResults").Show();

            Dl.Plugin<ExpandoObject>().Expando(new ExpandoOptions(
                "initiallyClosed", (result.passed ? true : false),
                "side", "left",
                "fullSurface", true
                ));
        }

    }
}